import ecs100.UI;

import java.util.*;

public class Pencil_3 {
    private double lastX;
    private double lastY;

    class Point {
        double x;
        double y;

        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public void erasePoint(Point toPoint) {
            UI.eraseLine(this.x, this.y, toPoint.x, toPoint.y);
        }

        public void connectPoint(Point toPoint){
            UI.drawLine(this.x, this.y, toPoint.x, toPoint.y);
        }
    }

    class ActionRecord {
        List<Point> points;

        public ActionRecord(List<Point> points) {
            this.points = points;
        }

        public void addPoint(double x, double y) {
            this.points.add(new Point(x, y));
        }

        public List<Point> getPoints() {
            return this.points;
        }
    }

    ActionRecord thisAction;
    Set<ActionRecord> allAction = new HashSet<>();
    Stack<ActionRecord> undoStack = new Stack<>();


    /**
     * Respond to mouse events
     */
    public void doMouse(String action, double x, double y) {
        if (action.equals("pressed")) {
            thisAction = new ActionRecord(new ArrayList<>());
            lastX = x;
            lastY = y;
            thisAction.addPoint(x, y);
        } else if (action.equals("dragged")) {
            UI.drawLine(lastX, lastY, x, y);
            lastX = x;
            lastY = y;
            thisAction.addPoint(x, y);
        } else if (action.equals("released")) {
            UI.drawLine(lastX, lastY, x, y);
            thisAction.addPoint(x, y);
            allAction.add(thisAction);
            undoStack.push(thisAction);
        }

    }

    public void setupGUI() {
        UI.setMouseMotionListener(this::doMouse);
        UI.addButton("Quit", UI::quit);
        UI.addButton("Undo", () -> {
            if (undoStack.isEmpty()) {
                return;
            }

            ActionRecord actionRecord = this.undoStack.pop();
            List<Point> undoPoints = actionRecord.getPoints();
            for (int i = 0; i < undoPoints.size() - 1; i++) {
                Point point1 = undoPoints.get(i);
                Point point2 = undoPoints.get(i + 1);
                point1.erasePoint(point2);
            }

            allAction.remove(actionRecord);
            for (ActionRecord otherAction : allAction) {
                List<Point> points = otherAction.getPoints();
                for (int i = 0; i < points.size() - 1; i++) {
                    Point point1 = points.get(i);
                    Point point2 = points.get(i + 1);
                    point1.connectPoint(point2);
                }
            }
        });
        UI.setLineWidth(3);
        UI.setDivider(0.0);
    }

    public static void main(String[] arguments) {
        new Pencil_3().setupGUI();
    }

}
